package icu.ac.kr.simpleRssReader.parser;

import icu.ac.kr.simpleRssReader.provider.RssDBProviderConstant;

import java.util.HashMap;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

import android.content.ContentResolver;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
import android.util.Log;

public class WebParser extends DefaultHandler {

	static final String TAG = "WebParser";
	
	static int currentState = 1;
	static int currentIndex = 1;
	
	static final int CHANNEL = 1 << 1;  // 0010
	static final int ITEM = 1 << 2;	 	// 0100
	
	static final int TITLE = 1 << 3;
	static final int DESCRIPTION = 1 << 4;
	static final int PUBDATE = 1 << 5;
	
	public PostEntity postEntity;
	public long channelId = 0;
	
	static final HashMap<String, Integer> tagFilter = new HashMap <String, Integer>();
	 
	static {
		tagFilter.put("title", new Integer(TITLE));
		tagFilter.put("description", new Integer(DESCRIPTION));
		tagFilter.put("pubDate", new Integer(PUBDATE));
	}
	
	ContentResolver cp;
	String url;
	public WebParser(ContentResolver cp, String addr) {
		// TODO Auto-generated constructor stub
	
		this.cp = cp;
		url = addr;
	
	}

	@Override
	public void characters(char[] ch, int start, int length)
			throws SAXException {
		// TODO Auto-generated method stub
		super.characters(ch, start, length);
		//Log.d(TAG, "character :" + new String(ch, start, length));

		switch (currentIndex)
		{
		case TITLE:
			if ((currentState & CHANNEL) != 0)
			{
				Log.d(TAG, "Channel TITLE : "+ new String(ch, start, length));
				currentState = 1;
				
				ContentValues values = new ContentValues();
				values.put("title", new String(ch, start, length));
				values.put("url", url);
				
				Uri uri = cp.insert(RssDBProviderConstant.CHANNEL_URI, values);
				channelId = Long.parseLong(uri.getPathSegments().get(1));
				if (channelId == -1)
				{
					// in case of refresh
					Cursor cursor = cp.query(RssDBProviderConstant.CHANNEL_URI, new String[] {"_id"}, "url='"+url+"'", null, null);
					cursor.moveToFirst();
					channelId = cursor.getLong(cursor.getColumnIndex(RssDBProviderConstant.channel._ID));
					Log.d(TAG, "-1  => Channel ID :" +channelId);
					cursor.close();
				}
				
				// store in DB via CP
			
			}
			else if ((currentState & ITEM) != 0)
			{
				Log.d(TAG, "adding title to Item structure");
				Log.d(TAG, "Post TITLE : "+ new String(ch, start, length));
				postEntity.title = new String(ch, start, length);
			}	
			currentIndex = 1;
			
			break;
		case DESCRIPTION:
			if ((currentState & ITEM) != 0)
			{	
				Log.d(TAG, "Post Description : "+ new String(ch, start, length));
				postEntity.description = new String(ch, start, length);
				currentIndex = 1;
			}
			break;
		case PUBDATE:
			if ((currentState & ITEM) != 0)
			{
				Log.d(TAG, "Post pubdate : "+ new String(ch, start, length));
				postEntity.pubdate = new String(ch, start, length);
				currentIndex = 1;
			}
			break;
		}
		
	}

	@Override
	public void endElement(String uri, String localName, String name)
			throws SAXException {
		// TODO Auto-generated method stub
		super.endElement(uri, localName, name);
		Log.d(TAG, "EndElement : " +name);
		
		if (name.equals("item"))
		{
			Log.d(TAG, "Closing Item discovered");
			// store the postentity to DB via CP
			
			ContentValues values = new ContentValues();
			values.put("title", postEntity.title);
			values.put("body", postEntity.description);
			values.put("pubdate", postEntity.pubdate);
			// for ChannelID....between refresh and new 
			values.put("channel_id", channelId);
			
			cp.insert(RssDBProviderConstant.POST_URI, values);
			currentState = 1;
		}	
	}

	@Override
	public void startElement(String uri, String localName, String name,
			Attributes attributes) throws SAXException {
		// TODO Auto-generated method stub
		super.startElement(uri, localName, name, attributes);
	
		Log.d(TAG, "StartElement : " +name);
	 
		if (name.equals("channel"))
			currentState |= CHANNEL;
		
		if (name.equals("item"))
		{
			currentState &= ~CHANNEL;
			currentState |= ITEM;
		}
	
		Integer tag = tagFilter.get(name);
		
		if (tag != null)
		
		{	
			switch (tag.intValue())
			{
			case TITLE:
				if ((currentState & CHANNEL) != 0)
				{
					Log.d(TAG, "TITLE discovered");
				}
				else if ((currentState & ITEM) != 0)
				{
					Log.d(TAG, "Item discovered");
					Log.d(TAG, "Item structure generated");
					Log.d(TAG, "adding title to Item structure");
					postEntity = new PostEntity();
				}	
				currentIndex = TITLE;
				break;
			case DESCRIPTION:
				if ((currentState & ITEM) != 0)
					currentIndex = DESCRIPTION;
				
				break;
			case PUBDATE:
				if ((currentState & ITEM) != 0)
					currentIndex = PUBDATE;
				break;
			}
		}
		
	}

	private class PostEntity{
		
		public String title;
		public String description;
		public String pubdate;
		
	}
	
}

